function _execute(
  invokeID: string,
  apiName: string,
  param: any,
  successCallBackName: string,
  failedCallBackName: string
) {
  try {
    if (param && typeof param !== 'string') {
      param = JSON.stringify(param)
    }
  } catch (e) {
    throw new Error(e.message)
  }
  var src =
    'emm-services://?action=jsfunction' +
    '&invokeID=' +
    (invokeID || '') +
    '&apiname=' +
    (apiName || '') +
    '&param=' +
    encodeURIComponent(param || '') +
    '&oncallback=' +
    (successCallBackName || '') +
    '&errorcallback=' +
    (failedCallBackName || '')
  var element = document.createElement('iframe')
  element.setAttribute('src', src)
  element.setAttribute('style', 'display:none')
  element.setAttribute('width', '0px')
  element.setAttribute('height', '0px')
  element.setAttribute('frameborder', '0px')
  document.body.appendChild(element)
  element.parentNode?.removeChild(element)

  console.info('successCallBackName', successCallBackName)
  console.info('failedCallBackName', failedCallBackName)
  console.info('invokeID', invokeID)
}

window.JQAPICallBack = {
  callBackObjects: {},
  //接口执行成功回调
  successCallBack: function (invokeID: string, data: any) {
    this.callBackObjects[invokeID].successCallBack(data)
    delete this.callBackObjects[invokeID]
  },
  //接口执行失败回调
  failedCallBack: function (invokeID: string, data: any) {
    this.callBackObjects[invokeID].failedCallBack(data)
    delete this.callBackObjects[invokeID]
  }
}

class JQAPIFactory {
  successCallBack: Function
  failedCallBack: Function

  constructor(
    invokeID: string,
    APIName: string,
    param: any,
    successCallBack: Function,
    failedCallBack: Function
  ) {
    if (
      typeof successCallBack !== 'function' ||
      typeof failedCallBack !== 'function'
    ) {
      throw new Error('callback must be a function.')
    }
    this.successCallBack = successCallBack
    this.failedCallBack = failedCallBack
    _execute(
      invokeID,
      APIName,
      param,
      'JQAPICallBack.successCallBack',
      'JQAPICallBack.failedCallBack'
    )
  }
}

const JQAPI = (name: string, extra_params: any) => {
  if (!name) {
    console.log('输入方法名')
    return
  }
  extra_params = extra_params || {}
  let { param, successCallBack, failedCallBack } = extra_params
  let invokeID = name + new Date().getTime()
  let params: [string, string, unknown, Function, Function] = [
    invokeID,
    name,
    param || '',
    successCallBack || function () {},
    failedCallBack ||
      function (msg: string) {
        throw new Error(msg)
      }
  ]
  window.JQAPICallBack.callBackObjects[invokeID] = new JQAPIFactory(...params)
}

export default (name: string, param: any) => {
  return new Promise((resolve) => {
    JQAPI(name, {
      param,
      successCallBack(data: string) {
        let _data: any = JSON.parse(data)
        resolve([null, _data])
      },
      failedCallBack(err: any) {
        resolve([err, {}])
      }
    })
  })
}
